package com.test.client;

import android.util.Log;



import java.io.BufferedWriter;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStreamWriter;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.Date;
import java.util.List;
import java.util.Locale;



public class LogUtil {

    private static final boolean ENABLE_LOG_FILE = false;
    //单例
    private static LogUtil logUtil;
    //打印调试开关
    private static boolean IS_DEBUG = true;
    //Log 单词打印的最大长度
    private static final int MAX_LENGTH = 3 * 1024;

    //单例模式初始化
    public static LogUtil getInstance() {
        if (logUtil == null) {
            logUtil = new LogUtil();

        }
        return logUtil;
    }

    private static String path = null;//log日志存放路径

    private static SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss:SSS ", Locale.US);//日期格式;

    private static Date date = new Date();//因为log日志是使用日期命名的，使用静态成员变量主要是为了在整个程序运行期间只存在一个.log文件中;

    /**
     * 初始化，须在使用之前设置，最好在Application创建时调用
     */
    public   void init() {
        //path =StorageUtils.getLogDir() ;
    }


    //获取指定目录下一级文件
    public static List<File> getDirAllFile(File file) {
        List<File> fileList = new ArrayList<>();
        File[] fileArray = file.listFiles();
        if(fileArray == null)
            return fileList;
        for (File f : fileArray) {
            fileList.add(f);
        }
        fileSortByTime(fileList);
        return fileList;
    }
    //对文件进行时间排序
    public static void fileSortByTime(List<File> fileList) {
        Collections.sort(fileList, new Comparator<File>() {
            public int compare(File p1, File p2) {
                if (p1.lastModified() < p2.lastModified()) {
                    return -1;
                }
                return 1;
            }
        });
    }
    public   void removeFileByTime(String dirPath) {
        //获取目录下所有文件
        List<File> allFile = getDirAllFile(new File(dirPath));
        SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm");
        //获取当前时间
        Date end = new Date(System.currentTimeMillis());
        try {
            end = dateFormat.parse(dateFormat.format(new Date(System.currentTimeMillis())));
        } catch (Exception e){
            e.printStackTrace();
        }
        for (File file : allFile) {//ComDef
            try {
                //文件时间减去当前时间
                Date start = dateFormat.parse(dateFormat.format(new Date(file.lastModified())));
                long diff = end.getTime() - start.getTime();//这样得到的差值是微秒级别
               long days = diff / (1000 * 60 * 60 * 24);
             //   long days = diff;
                if(3 <= days){
                    deleteFile2(file);
                }

            } catch (Exception e){
                e.printStackTrace();
            }
        }
    }

    //删除文件夹及文件夹下所有文件
    public static void deleteFile2(File file) {
        if (file.isDirectory()) {
            File[] files = file.listFiles();
            for (int i = 0; i < files.length; i++) {
                File f = files[i];
                deleteFile2(f);
            }
            file.delete();
        } else if (file.exists()) {
            file.delete();
        }
    }

    /**
     * 获取 TAG 信息：文件名以及行数
     *
     * @return TAG 信息
     */
    private synchronized String getTAG() {
        StringBuilder tag = new StringBuilder();
        StackTraceElement[] sts = Thread.currentThread().getStackTrace();
        if (sts == null) {
            return "";
        }
        for (StackTraceElement st : sts) {
            //筛选获取需要打印的TAG
            if (!st.isNativeMethod() && !st.getClassName().equals(Thread.class.getName()) && !st.getClassName().equals(this.getClass().getName())) {
                //获取文件名以及打印的行数
                tag.append("(").append(st.getFileName()).append(":").append(st.getLineNumber()).append(")");
                return tag.toString();
            }
        }
        return "";
    }

    /**
     * Log.e 打印
     *
     * @param text 需要打印的内容
     */
    public synchronized void e(String text) {
        if (text ==null){
            Log.w(getTAG(), "传入的数据为空");
            return;
        }
        if (IS_DEBUG) {
            for (String str : splitStr(text)) {
                Log.e(getTAG(), str);
                if (ENABLE_LOG_FILE){
                    writeToFile('e',getTAG(),str);
                }

            }
        }
    }

    /**
     * Log.d 打印
     *
     * @param text 需要打印的内容
     */
    public synchronized void d(String text) {
        if (text ==null){
            Log.w(getTAG(), "传入的数据为空");
            return;
        }


        if (IS_DEBUG) {
            for (String str : splitStr(text)) {

                Log.d(getTAG(), str);

                if (ENABLE_LOG_FILE){
                    writeToFile('d',getTAG(),str);
                  //  Log.d("日志写入文件",getTAG()+"===="+str);
                }

            }
        }
    }

    /**
     * Log.w 打印
     *
     * @param text 需要打印的内容
     */
    public synchronized void w(String text) {
        if (text ==null){
            Log.w(getTAG(), "传入的数据为空");
            return;
        }
        if (IS_DEBUG) {
            for (String str : splitStr(text)) {
                Log.w(getTAG(), str);
                if (ENABLE_LOG_FILE){
                    writeToFile('w',getTAG(),str);
                }

            }
        }
    }

    /**
     * Log.i 打印
     *
     * @param text 需要打印的内容
     */
    public synchronized void i(String text) {
        if (text ==null){
            Log.w(getTAG(), "传入的数据为空");
            return;
        }
        if (IS_DEBUG) {
            for (String str : splitStr(text)) {
                Log.i(getTAG(), str);
                if (ENABLE_LOG_FILE){
                    writeToFile('i',getTAG(),str);
                }

            }
        }
    }



    /**
     * 将log信息写入文件中
     *
     * @param type
     * @param tag
     * @param msg
     */
    private   void writeToFile(char type, String tag, String msg) {

        if (null == path) {
            Log.e(getTAG() ,"logPath == null ，未初始化LogToFile");
            return;
        }
     /*   String dataPath = StorageUtils.getDataPath();
        if (dataPath == null || dataPath.length() <= 0) {
            // 无SD卡，则设置为data目录下
            dataPath = "/data";
        }
            final long INTERNAL_MINI_SIZE = 100L * 1024 * 1024;
        // 获取data目录下的存储空间
        long systemSize = StorageUtils.getAvailableSpace(dataPath);
        if (systemSize < INTERNAL_MINI_SIZE) {
            return;
        }*/


        String fileName = path + "/log.log";//log日志名，使用时间命名，保证不重复
        String log = dateFormat.format(System.currentTimeMillis()) + " " + type + " " + tag + " " + msg + "\n";//log日志内容，可以自行定制

        //如果父路径不存在
        File file = new File(path);
        if (!file.exists()) {
            file.mkdirs();//创建父路径
        }



        FileOutputStream fos = null;//FileOutputStream会自动调用底层的close()方法，不用关闭
        BufferedWriter bw = null;
        try {

            fos = new FileOutputStream(fileName, true);//这里的第二个参数代表追加还是覆盖，true为追加，flase为覆盖
            bw = new BufferedWriter(new OutputStreamWriter(fos));
            bw.write(log);

        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            try {
                if (bw != null) {
                    bw.close();//关闭缓冲流
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
        }

    }


    /**
     * Log.e 打印格式化后的JSON数据
     *
     * @param json 需要打印的内容
     */
    public synchronized void json(String json) {
        if (IS_DEBUG) {
            String tag = getTAG();
            try {
                //转化后的数据
                String logStr = formatJson(json);
                for (String str : splitStr(logStr)) {
                    Log.e(getTAG(), str);
                }
            } catch (Exception e) {
                e.printStackTrace();
                Log.e(tag, e.toString());
            }
        }
    }

    /**
     * 数据分割成不超过 MAX_LENGTH的数据
     *
     * @param str 需要分割的数据
     * @return 分割后的数组
     */
    private String[] splitStr(String str) {
        //字符串长度
        int length = str.length();
        //返回的数组
        String[] strs = new String[length / MAX_LENGTH + 1];
        //
        int start = 0;
        for (int i = 0; i < strs.length; i++) {
            //判断是否达到最大长度
            if (start + MAX_LENGTH < length) {
                strs[i] = str.substring(start, start + MAX_LENGTH);
                start += MAX_LENGTH;
            } else {
                strs[i] = str.substring(start, length);
                start = length;
            }
        }
        return strs;
    }


    /**
     * 格式化
     *
     * @param jsonStr json数据
     * @return 格式化后的json数据
     * @author lizhgb
     * @link https://my.oschina.net/jasonli0102/blog/517052
     */
    private String formatJson(String jsonStr) {
        if (null == jsonStr || "".equals(jsonStr))
            return "";
        StringBuilder sb = new StringBuilder();
        char last = '\0';
        char current = '\0';
        int indent = 0;
        boolean isInQuotationMarks = false;
        for (int i = 0; i < jsonStr.length(); i++) {
            last = current;
            current = jsonStr.charAt(i);
            switch (current) {
                case '"':
                    if (last != '\\') {
                        isInQuotationMarks = !isInQuotationMarks;
                    }
                    sb.append(current);
                    break;
                case '{':
                case '[':
                    sb.append(current);
                    if (!isInQuotationMarks) {
                        sb.append('\n');
                        indent++;
                        addIndentBlank(sb, indent);
                    }
                    break;
                case '}':
                case ']':
                    if (!isInQuotationMarks) {
                        sb.append('\n');
                        indent--;
                        addIndentBlank(sb, indent);
                    }
                    sb.append(current);
                    break;
                case ',':
                    sb.append(current);
                    if (last != '\\' && !isInQuotationMarks) {
                        sb.append('\n');
                        addIndentBlank(sb, indent);
                    }
                    break;
                default:
                    sb.append(current);
            }
        }

        return sb.toString();
    }

    /**
     * 在 StringBuilder指定位置添加 space
     *
     * @param sb     字符集
     * @param indent 添加位置
     * @author lizhgb
     * @link https://my.oschina.net/jasonli0102/blog/517052
     */
    private void addIndentBlank(StringBuilder sb, int indent) {
        for (int i = 0; i < indent; i++) {
            sb.append('\t');
        }
    }




}